package org.example.service;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.*;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


@ClientEndpoint
@Slf4j
public class MyClient {

    private Session session;
    private String name = "default";
    private boolean isSending = false;//控制websocket只有一个消息在发送
    private final AtomicInteger retryCount = new AtomicInteger(0);
    private static final int MAX_RETRIES = 3;
    public int type = 0;

    public MyClient() {
    }

    public MyClient(String name) {
        this.name = name;
    }

    @OnOpen
    public void open(Session session){
        this.session = session;
        this.session.setMaxTextMessageBufferSize(10*1024*1024);
        log.info("session :{}  {} Client WebSocket is opening...",this.session.getId(),this.name);
    }

    @OnMessage
    public void onMessage(String message){
        log.info("{} Server send message: {}",this.name, message);
        JSONObject jsonobject = JSON.parseObject(message);
//        type = (int)jsonobject.get("type");
    }

    @OnClose
    public void onClose(){
        log.info("{} Websocket closed",this.name);
    }

    @OnError
    public void onError(Session session, Throwable t){
        log.info("{} onerror:{}",this.name,t.getMessage());
    }


    /**
     * 发送客户端消息到服务端
     * @param message 消息内容
     */
    public void send(String message){
        // 非阻塞方式：若正在发送，直接返回或加入队列
//        if (!session.isOpen() || isSending) {
//            log.info("WebSocket未就绪或正在发送，消息加入队列: {}", message);
//            return; // 或加入队列等待处理
//        }

        isSending = true;
        retryCount.set(0);
        doSend(message);
    }

    private void doSend(String message){
        if (retryCount.incrementAndGet() > MAX_RETRIES) {
            log.error("达到最大重试次数，消息发送失败: {}", message);
            isSending = false;
            return;
        }

        log.info("尝试发送消息 (第{}次): {}", retryCount.get(), message);
        session.getAsyncRemote().sendText(message, result -> {
            if (result.isOK()) {
                log.info("消息发送成功: {}", message);
                isSending = false;
            } else {
                log.error("消息发送失败，准备重试: {}", result.getException().getMessage());
                // 延迟重试（避免频繁重试）
                ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
                executor.schedule(() -> doSend(message), 1, TimeUnit.SECONDS);
                executor.shutdown();
            }
        });
    }

    public void close() throws IOException {
        session.close();
    }

    public boolean isOpened(){
        return session.isOpen();
    }
}
